home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / Mixed Mode Maddness / Emulator / Source / debug.c next >
Encoding:
C/C++ Source or Header  |  2000-06-24  |  24.4 KB  |  661 lines

  1. #include <Types.h>                            // include prototype
  2. #include <stdArg.h>                            // include prototype
  3.  
  4. #include "debug.h"
  5.  
  6. Boolean TrapAvailable(unsigned short);
  7.  
  8.  
  9.  
  10. // argument types passed
  11. #define kSHORT_ARG            1                // argument is a short
  12. #define kLONG_ARG            2                // argument is a long
  13. #define kINT_ARG                3                // argument is an int    
  14. #define kCHAR_ARG            4                // argument is a char
  15. #define kSTRING_ARG            5                // argument is a C string
  16. #define kPSTRING_ARG            6                // argument is a Pascal string
  17. #define kUknown_ARG            -1                // unknown argument type
  18. #define kMAX_LEN                255                // maximum output length
  19.  
  20. // format control tokens
  21. #define kFORMAT_TOKEN        '%'                // start of format sequence    
  22. #define kLEADINGZERO_TOKEN    '.'                // start leading zeros token
  23. #define kLEFTJUSTIFY_TOKEN        '-'                // left justify token
  24. #define kPLUS_TOKEN            '+'                // positive sign output token
  25. #define kSPACE_TOKEN            ' '                // space for sign output token
  26. #define kNULL_TOKEN            0x00            // null token end of input
  27.  
  28. // format modifier tokens
  29. #define kUP_LONG_TOK            'L'                // long modifier
  30. #define kLOW_LONG_TOK        'l'                //         "
  31. #define kUP_SHORT_TOK        'H'                // short modifier
  32. #define kLOW_SHORT_TOK        'h'                //         "
  33. #define kUP_DEC_TOK            'D'                // signed decimal modifier
  34. #define kLOW_DEC_TOK        'd'                //        "
  35. #define kUP_UNS_TOK            'U'                // unsigned decimal modifier
  36. #define kLOW_UNS_TOK        'u'                //        "
  37. #define kUP_HEX_TOK            'X'                // hex modifier
  38. #define kLOW_HEX_TOK        'x'                //     "
  39. #define kUP_OCT_TOK            'O'                // octal modifier
  40. #define kLOW_OCT_TOK        'o'                //     "
  41. #define kUP_CHAR_TOK            'C'                // char modifier
  42. #define kLOW_CHAR_TOK        'c'                //        "
  43. #define kUP_STR_TOK            'S'                // C string modifier
  44. #define kLOW_STR_TOK            's'                //        "
  45. #define kUP_PSTR_TOK            'P'                // Pascal string modifier
  46. #define kLOW_PSTR_TOK        'p'                //        "
  47. #define kUP_BIN_TOK            'B'                //    Binnary modifier
  48. #define kLOW_BIN_TOK            'b'                //        "
  49.  
  50. // char constants
  51. #define kSpace_CHAR            ' '                // ASCII value of a space
  52. #define kZero_CHAR            '0'                // ASCII value of zero
  53. #define kNine_CHAR            '9'                // ASCII value of nine
  54. #define kHexTEN_UP_CHAR        'A'                // ASCII value to represent Hex ten Upper case
  55. #define kHexTEN_LO_CHAR        'a'                // ASCII value to represent Hex ten Lowwer case
  56. #define kUndefined_CHAR        '#'                // ASCII value to output for an undefined format
  57. #define kMINUS_CHAR            '-'                // ASCII value to show negative number
  58. #define kPLUS_CHAR            '+'                // ASCII value to show positive number
  59.  
  60. // numeric constants
  61. #define kBinary_BASE            2                // binary equals base two    
  62. #define kOctal_BASE            8                // octal equals base eight
  63. #define kDecmal_BASE            10                // decimal equals base ten
  64. #define kHex_BASE            16                // hex equals base sixteen
  65. #define kNumDecDigits            ((9 - 0)+1)         // number of numeric decimal digits
  66. #define kBYTE_MASK            0xFF                // mask for a byte value
  67. #define kBITS_PER_BYTE            0x08            // number of bits in a byte
  68.  
  69. // internal function to convert a 32 bit number to any base with format control
  70. static short numtobase(long numin, unsigned short base, char* str, 
  71.         short zpaddlen, short spacepaddlen, short argtype, char ten_char,
  72.         Boolean usesign, Boolean useplus, Boolean usespace, Boolean leftjustify);
  73.  
  74. // internal function to parse a numeric value
  75. static char* parse_numeric_value(char* pbuffer, short *value);
  76.  
  77. // internal function to look at the next token
  78. static char Peek_Token(char* pbuffer);
  79.  
  80. // internal function to poop the next token
  81. static char * Get_Next_Token(char* pbuffer, char* token);
  82.  
  83. // internal function to output a char into a buffer
  84. static char* Output_Char(char* pbuffer, char token, short * length);
  85.  
  86. /*-----------------------------------------------------------------------
  87. * void MyDebugStr(char * pbuffer, ...)
  88. *  PURPOSE:
  89. *             drop into debugger with formater string
  90. *
  91. * In:        pbuffer - pointer to debug format string NULL TERMINATED
  92. *
  93. *
  94. *                      format commands
  95. *                      %                        - start format sequence
  96. *                      -                        - left justify
  97. *                      +                        - use sign
  98.                      ' '                        - use space for plus and a minus for negative
  99. *                      n                        - min field width
  100. *                      .m                        - min leading zero's
  101. *                      L                        - long modifier
  102. *
  103. *                      %[-][n][.m][L]B            - display binnary number
  104. *                      %[-][n][.m][L]O            - display octal number
  105. *                      %[-][n][.m][L]X            - display hex number
  106. *                      %[-][+][n][.m][L]D        - display decimal number
  107. *                      %[-][n][.m][L]U            - display unsigned number
  108. *                      %[-][n]S                - display C string
  109. *                      %[-][n]P                - display a Pascal string
  110. *                      %[-][n]C                  - display a charactor
  111. *                      %%                    - display %
  112. *
  113. *            args    - format arguments MUST MATCH commands!!!
  114. *
  115. *
  116. *----------------------------------------------------------------------*/
  117. void Debug(char* pbuffer, ...)
  118. {
  119.     va_list next_Arg;                                            // next argument to process
  120.     char poutput[kMAX_LEN + 1];                                    // output buffer
  121.     char *ptemp;                                                // temp string pointer
  122.     char *poutptr;                                                // current output pointer
  123.     char *p;                                                    // string argument pointer
  124.     long num;                                                // number to convert
  125.     short plen;                                                // length of string pointer
  126.     short zpaddlen;                                            // leading zero
  127.     short spacepaddlen;                                        // leading space padd length
  128.     short    strlength;                                            // string length
  129.     short length;                                                // num bytes in output buffer
  130.     short argtype;                                                // type of argument passed
  131.     unsigned short base;                                        // base of output number
  132.     char ch;                                                    // char argument
  133.     char token;                                                // current token
  134.     char token_peek;                                            // next token
  135.     char ten_char;                                                // either 'A' or 'a'
  136.     Boolean usesign;                                            // number is a signed numeric value
  137.     Boolean useplus;                                            // use a plus sign if positive
  138.     Boolean usespace;                                            // use a space if positive
  139.     Boolean leftjustify;                                            // use left justification
  140.  
  141.     va_start(next_Arg, pbuffer);                                    // start the var args
  142.  
  143.     zpaddlen = 0;                                                // init zero padd
  144.     spacepaddlen = 0;                                            // init space padd
  145.  
  146.     length = 0;                                                // init length
  147.     poutptr = poutput+1;                                        // init output pointer (byte 0 is length byte)
  148.     do {                                                        // process format string until end of input
  149.                                                             // or max output length is reached
  150.         pbuffer = Get_Next_Token(pbuffer, &token);                // get the current token
  151.  
  152.         switch (token) {                                        // key off of current token
  153.  
  154.             case kFORMAT_TOKEN:                                // start of format sequence
  155.                 token_peek = Peek_Token(pbuffer);                // look at next token
  156.                 
  157.                 if (token_peek) {                                // check for end of input
  158.  
  159.                     if (token_peek == kFORMAT_TOKEN) {            // check for sequence %%
  160.                         pbuffer = Get_Next_Token(pbuffer, &token);
  161.                                                             // output a %
  162.                         poutptr = Output_Char(poutptr, kFORMAT_TOKEN, &length);
  163.                         break;                                // done with this sequence
  164.                     }
  165.  
  166.                     leftjustify = false;                            // init left justify to false
  167.                     usesign = false;                            // init to unsigned output
  168.                     useplus = false;                            // dont force sign to be outputed
  169.                     usespace = false;                            // dont force sign spaceing to be outputed
  170.                     argtype = kUknown_ARG;                    // init argumnent type
  171.  
  172.                     if (token_peek == kLEFTJUSTIFY_TOKEN) {        // check for sequence %-
  173.                                                             // get the token
  174.                         pbuffer = Get_Next_Token(pbuffer, &token);
  175.                         token_peek = Peek_Token(pbuffer);        // look at next token
  176.                         leftjustify = true;                        // turn on left justify
  177.                     }
  178.                     
  179.                     if (token_peek == kPLUS_TOKEN) {                // check for sequence %+
  180.                                                             // get the token
  181.                         pbuffer = Get_Next_Token(pbuffer, &token);
  182.                         token_peek = Peek_Token(pbuffer);        // look at next token
  183.                         useplus = true;                            // turn on plus sign
  184.                     }
  185.                     else {
  186.                         if (token_peek == kSPACE_TOKEN) {        // check for sequence %' '
  187.                                                             // get the token
  188.                             pbuffer = Get_Next_Token(pbuffer, &token);
  189.                             token_peek = Peek_Token(pbuffer);    // look at next token
  190.                             usespace = true;                    // turn on space for sign
  191.                         }
  192.                     }
  193.                                                             // check for specified leading space
  194.                                                             // field width
  195.                     if ((token_peek >= kZero_CHAR) && (token_peek <= kNine_CHAR)) {
  196.                         pbuffer = parse_numeric_value(pbuffer, &spacepaddlen);
  197.                         token_peek = Peek_Token(pbuffer);        // look at next token
  198.                     }
  199.                     if (token_peek == kLEADINGZERO_TOKEN) {        // check for start of leading zero sequence
  200.                         pbuffer = Get_Next_Token(pbuffer, &token);
  201.                         token_peek = Peek_Token(pbuffer);        // look at next token
  202.                                                             // parse leading zero length
  203.                         if ((token_peek >= kZero_CHAR) && (token_peek <= kNine_CHAR)) {
  204.                             pbuffer = parse_numeric_value(pbuffer, &zpaddlen);
  205.                             token_peek = Peek_Token(pbuffer);    // look at next token
  206.                         }
  207.                     }
  208.                     
  209.                     if (! (token_peek)) {                        // check for end of buffer
  210.                         break;
  211.                     }
  212.  
  213.                     argtype = kINT_ARG;                        // default to int argument
  214.                     if ((token_peek == kUP_LONG_TOK) || (token_peek == kLOW_LONG_TOK)) {
  215.                         argtype = kLONG_ARG;                    // long modifier
  216.                         pbuffer = Get_Next_Token(pbuffer, &token);
  217.                         token_peek = Peek_Token(pbuffer);        // look at next token
  218.                     }
  219.                     else {
  220.                         if ((token_peek == kUP_SHORT_TOK) || (token_peek == kLOW_SHORT_TOK)) {
  221.                             argtype = kSHORT_ARG;                // short modifier
  222.                             pbuffer = Get_Next_Token(pbuffer, &token);
  223.                             token_peek = Peek_Token(pbuffer);    // look at next token
  224.                         }
  225.                     
  226.                     }
  227.                     if (!token_peek) {                            // check for end of buffer
  228.                         break;
  229.                     }
  230.                     switch (token_peek) {                        // key off token
  231.                         case kUP_DEC_TOK:
  232.                         case kLOW_DEC_TOK:                    // signed decimal number
  233.                             base = kDecmal_BASE;                // set base to 10
  234.                             usesign = true;                        // and use sign
  235.                             break;
  236.  
  237.                         case kUP_UNS_TOK:
  238.                         case kLOW_UNS_TOK:                    // unsigned decimal number
  239.                             base = kDecmal_BASE;                // set base to 10
  240.                             usesign = false;                    // do not use sign
  241.                             break;
  242.  
  243.                         case kUP_HEX_TOK:    
  244.                             base = kHex_BASE;                    // set base to 16
  245.                             usesign = false;                    // do not use sign
  246.                             ten_char = kHexTEN_UP_CHAR;        // lowwer case hex
  247.                             break;
  248.  
  249.                         case kLOW_HEX_TOK:                    // hex number
  250.                             base = kHex_BASE;                    // set base to 16
  251.                             usesign = false;                    // do not use sign
  252.                             ten_char = kHexTEN_LO_CHAR;        // lowwer case hex
  253.                             break;
  254.  
  255.                         case kUP_OCT_TOK:
  256.                         case kLOW_OCT_TOK:                    // octal number
  257.                             base = kOctal_BASE;                // set base to 8
  258.                             usesign = false;                    // do not use sign
  259.                             break;
  260.  
  261.                         case kUP_BIN_TOK:    
  262.                         case kLOW_BIN_TOK:                    // binnary number
  263.                             base = kBinary_BASE;                // set base to 2
  264.                             usesign = false;                    // do not use sign
  265.                             break;
  266.  
  267.                         case kUP_CHAR_TOK:
  268.                         case kLOW_CHAR_TOK:                    // char
  269.                             argtype = kCHAR_ARG;                // set argtype to char
  270.                             break;
  271.                         case kUP_STR_TOK:
  272.                         case kLOW_STR_TOK:                    // C string
  273.                              argtype = kSTRING_ARG;            // set argtype to C string
  274.                              break;
  275.  
  276.                         case kUP_PSTR_TOK:
  277.                         case kLOW_PSTR_TOK:                    // Pascal string
  278.                              argtype = kPSTRING_ARG;            // set argtype to Pascal string
  279.                              break;
  280.  
  281.                         default:                                // invalid token (should never get here)
  282.                                                             // output a char to show invalid
  283.                             poutptr = Output_Char(poutptr, kUndefined_CHAR, &length);
  284.                             break;
  285.                     }                                        // end format control sequence
  286.  
  287.                     pbuffer = Get_Next_Token(pbuffer, &token);    // pop token off the stack
  288.  
  289.                     switch (argtype) {                            // key of argument type to process
  290.  
  291.                         case kINT_ARG:                        // argument is a int value
  292.                                                             // get next short argument
  293.                             num = (long)(va_arg(next_Arg,int));
  294.                                                             // format the number
  295.                             strlength = numtobase(num, base, poutptr, zpaddlen,
  296.                                     spacepaddlen, argtype, ten_char, usesign, 
  297.                                         useplus, usespace, leftjustify);
  298.                             poutptr += strlength;                // increment output buffer
  299.                             length += strlength;                    // increment output length
  300.                             break;
  301.  
  302.                         case kSHORT_ARG:                        // argument is a short value
  303.                                                             // get next short argument
  304.                             num = (long)(va_arg(next_Arg,short));
  305.                                                             // format the number
  306.                             strlength = numtobase(num, base, poutptr, zpaddlen,
  307.                                     spacepaddlen, argtype, ten_char, usesign, 
  308.                                         useplus, usespace, leftjustify);
  309.                             poutptr += strlength;                // increment output buffer
  310.                             length += strlength;                    // increment output length
  311.                             break;
  312.  
  313.                         case kLONG_ARG:                        // argument is a long value
  314.                             num = va_arg(next_Arg,long);        // get the next long argument
  315.                                                             // format the number
  316.                             strlength = numtobase(num, base, poutptr, zpaddlen,
  317.                                      spacepaddlen, argtype, ten_char, usesign, 
  318.                                         useplus, usespace, leftjustify);
  319.                             poutptr += strlength;                // increment output buffer
  320.                             length += strlength;                    // increment output length
  321.                             break;
  322.  
  323.                         case kCHAR_ARG:                        // argument is a char
  324.                                                             // note: char is put on stack as a short!
  325.                             ch = va_arg(next_Arg,short);            // get the char argument
  326.                             spacepaddlen --;                    // decrement leading space by 1
  327.                                                             // (since char output size equals one)
  328.                             if (leftjustify == false) {                // if right justified
  329.                                 for (; spacepaddlen > 0; ) {        // ouput spaces
  330.                                     poutptr = Output_Char(poutptr, kSpace_CHAR, &length);
  331.                                     spacepaddlen--;            // decrement counter
  332.                                 }
  333.                             }                                // ouput the char
  334.                             poutptr = Output_Char(poutptr, ch, &length);
  335.                             if (leftjustify) {                    // if left justfication
  336.                                 for (; spacepaddlen > 0; ) {        // output spaces
  337.                                     poutptr = Output_Char(poutptr, kSpace_CHAR, &length);
  338.                                     spacepaddlen--;            // decrement counter
  339.                                 }
  340.                             }
  341.                             break;
  342.  
  343.                         case kSTRING_ARG:                        // argument is a string
  344.                             p = (char*)va_arg(next_Arg,long);        // get string pointer argument
  345.                             ptemp = p;                        // assign a temp pointer
  346.                             for (strlength = 0; *ptemp; *ptemp++) {
  347.                                 strlength++;                    // calculate the length of the string
  348.                             }
  349.                             
  350.                             if (leftjustify == false) {                // if right justify
  351.                                                             // output leading spaces
  352.                                 for (; strlength < spacepaddlen; ) {
  353.                                     poutptr = Output_Char(poutptr, kSpace_CHAR, &length);
  354.                                     spacepaddlen--;            // decrement counter
  355.                                 }
  356.                             }
  357.                             for (; *p ;)  {                        // output the string
  358.                                                             // one char at a time
  359.                                 poutptr = Output_Char(poutptr, *p++, &length);
  360.                             }                                // until end null char
  361.  
  362.                             if (leftjustify) {                    // if left justify
  363.                                                             // output trailing spaces
  364.                                 for (; strlength < spacepaddlen; ) {
  365.                                     poutptr = Output_Char(poutptr, kSpace_CHAR, &length);
  366.                                     spacepaddlen--;            // decrement counter
  367.                                 }
  368.                             }
  369.                             break;
  370.  
  371.                         case kPSTRING_ARG:                    // argument is a Pascal string
  372.                             p = (char*)va_arg(next_Arg,long);        // get the string pointer argument
  373.                             strlength = *p++;                    // get length and increment pointer
  374.     
  375.                             if (leftjustify == false) {                // if right justify
  376.                                                             // output leading spaces
  377.                                 for (; strlength < spacepaddlen; ) {
  378.                                     poutptr = Output_Char(poutptr, kSpace_CHAR, &length);
  379.                                     spacepaddlen--;            // decrement count
  380.                                 }
  381.                             }
  382.                                                             // output the string
  383.                             for (plen = strlength; plen ; plen--)  {
  384.                                 poutptr = Output_Char(poutptr, *p++, &length);
  385.                             }
  386.                             if (leftjustify) {                    // if right justify
  387.                                                             // padd with trailing spaces
  388.                                 for (; strlength < spacepaddlen; ) {
  389.                                     poutptr = Output_Char(poutptr, kSpace_CHAR, &length);
  390.                                     spacepaddlen--;            // decrement buffer
  391.                                 }
  392.                             }
  393.                             break;
  394.                     }
  395.                 }
  396.                 break;
  397.         
  398.         case kNULL_TOKEN:                                        // null token
  399.             break;                                            // this is the end of input
  400.  
  401.         default:                                                // normal char
  402.             poutptr = Output_Char(poutptr, token, &length);            // output the char
  403.             break;
  404.         }                                                    // end token switch
  405.     } while ((token) && (length < kMAX_LEN));                        // end process input
  406.                                                             // when at end of string
  407.                                                             // or ouput buffer is full
  408.     *poutput = (char)length;                                        // get the length byte
  409. //    ParamText((StringPtr)poutput, nil, nil,nil);
  410.     
  411.     va_end(next_Arg);                                            // done processing arguments
  412.  
  413. //    Alert(1000, nil);
  414.     DebugStr((unsigned char*)poutput);
  415. }
  416.  
  417.  
  418. /*-----------------------------------------------------------------------
  419. * char* parse_numeric_value(char* pbuffer, short *value)
  420. *
  421. *  PURPOSE:
  422. *     parse a numeric from input buffer and assign to (*value)
  423. *
  424. *  char*    pbuffer:            IN            input buffer to parse
  425. *  short* value:            IN/OUT        numeric parsed value
  426. *
  427. *  RETURN
  428. *      current position of buffer
  429. *
  430. *----------------------------------------------------------------------*/
  431. static char* parse_numeric_value(char* pbuffer, short *value)
  432. {
  433.     short mulfactor;                                            // multiplication factor
  434.     
  435.     for (*value = 0, mulfactor = 1;                                    // get 1 digit at a time
  436.              ((*pbuffer >= kZero_CHAR) && (*pbuffer <= kNine_CHAR));
  437.                             *pbuffer++, mulfactor *= kNumDecDigits ) {
  438.         (*value) *= (mulfactor);                                    // multiply by 10 * digit number
  439.         (*value) += (*pbuffer - kZero_CHAR);                        // assign least significant digit
  440.         if ((*value) > kMAX_LEN) {                                // check for max length
  441.             (*value) = kMAX_LEN;                                // assign max length
  442.         }
  443.     }
  444.     return pbuffer;                                            // return current buffer pointer
  445. }
  446.  
  447.  
  448. /*-----------------------------------------------------------------------
  449. * static char Peek_Token(char* pbuffer)
  450. *
  451. *  PURPOSE:
  452. *         look at next token to process
  453. *            This was done just for code readability
  454. *
  455. *  char*    pbuffer:           IN            input buffer to parse
  456. *
  457. *  RETURN
  458. *      next token
  459. *
  460. *----------------------------------------------------------------------*/
  461. static char Peek_Token(char* pbuffer)
  462. {
  463.     return (*pbuffer);                                            // return current token
  464. }
  465.  
  466. /*-----------------------------------------------------------------------
  467. * static char * Get_Next_Token(char* pbuffer, char* token)
  468. *
  469. *  PURPOSE:
  470. *         look at next token to process
  471. *            This was done primaraly for code readability
  472. *
  473. *  char*    pbuffer:            IN            input buffer to parse
  474. *    char* token            IN/OUT        where to place the token
  475. *
  476. *  RETURN
  477. *      new buffer position
  478. *
  479. *----------------------------------------------------------------------*/
  480. static char * Get_Next_Token(char* pbuffer, char* token)
  481. {
  482.     *token = *pbuffer++;                                        // assign value
  483.                                                             // and increment buffer
  484.     return pbuffer;                                            // return new buffer position
  485. }
  486.  
  487. /*-----------------------------------------------------------------------
  488. * static char* Output_Char(char* pbuffer, char token, short * length)
  489. *
  490. *  PURPOSE:
  491. *        Output a token into the output buffer
  492. *
  493. *  char*    pbuffer:            IN/OUT        output buffer
  494. *    char token            IN            token to output
  495. *    short* length            IN/OUT        incremented by 1
  496. *
  497. *  RETURN
  498. *      new buffer position
  499. *
  500. *----------------------------------------------------------------------*/
  501. static char* Output_Char(char* pbuffer, char token, short * length)
  502. {
  503.     *pbuffer++ = token;                                            // put token in buffer
  504.                                                             // and increment buffer
  505.     (*length)++;                                                // increment length
  506.     return pbuffer;                                            // return new buffer position
  507. }
  508.  
  509. /*-----------------------------------------------------------------------
  510. * short numtobase(long numin, unsigned short base, char* str, short zpaddlen,
  511. *                        short zpaddlen, short spacepaddlen, short argtype, char ten_char,
  512. *                        Boolean usesign, Boolean forcesign, Boolean showspace, Boolean leftjustify)
  513. *
  514. *  PURPOSE:
  515. *     Convert a number to any base with leading spaces and zero's left or right justfied
  516. *
  517. *  long numin:                     IN            number to convert.
  518. *  unsigned short base:            IN            base to convert to (Must be kBinary_BASE or greater).
  519. *  char*    str:                       IN/OUT        Output string.
  520. *  short zpaddlen:                IN            max zero padding
  521. *  short spacepaddlen:            IN            max space padding
  522. *  short argtype:                IN            kSHORT_ARG or kLONG_ARG or INT_ARG
  523. *    char ten_char                IN            char to represent 10 hex
  524. *  Boolean usesign:                IN            use is a signed number
  525. *  Boolean showplus:            IN            display plus if positive display minus if negative
  526. *  Boolean showspace:            IN            display space if positive display minus if negative
  527. *  Boolean leftjustify:            IN            left justfy the output
  528. *
  529. *  RETURN
  530. *      length of output
  531. *
  532. *----------------------------------------------------------------------*/
  533.  
  534. static short numtobase(long numin, unsigned short base, char* str, 
  535.         short zpaddlen, short spacepaddlen, short argtype, char ten_char,
  536.         Boolean usesign, Boolean showplus, Boolean showspace, Boolean leftjustify)
  537. {
  538.     unsigned long num;                                        // unsigned version of number passed
  539.     char *s;                                                // current position in buffer
  540.     char *p1;                                                // temp pointer to output
  541.     char *p2;                                                // temp pointer to output
  542.     short len;                                                // length of output
  543.     short count;                                            // counter for spaces
  544.     short numspaces;                                        // number of spaces to output
  545.     short argsize;                                            // number of bytes of numin
  546.     char temp;                                            // temp char for byte swaping
  547.     Boolean negative;                                        // negative number flag
  548.  
  549.     negative = false;                                        // default to positive number
  550.  
  551.     if (base < kBinary_BASE) {                                // base must be at least two
  552.         return 0;                                            // return zero length output
  553.     }
  554.     if (usesign) {                                            // check sign flag
  555.         if (numin < 0) {                                        // check for negative number
  556.             numin = -numin;                                // get absolute value of number
  557.             negative = true;                                // set negative flag
  558.         }
  559.     }
  560.                                                         // determine the number of bytes of numin
  561.     switch (argtype) {                                        // case off argument type                                    
  562.         case kSHORT_ARG:                                    // arg is short
  563.             argsize = sizeof(short);                            // let compilier figure it out
  564.             break;
  565.             
  566.         case kLONG_ARG:                                    // arg is a long
  567.             argsize = sizeof(long);                            // let compilier figure it out
  568.             break;
  569.             
  570.         case kINT_ARG:                                    // arg is init
  571.             argsize = sizeof(int);                            // let compilier figure it out
  572.             break;
  573.             
  574.         default:                                            // unknown argument 
  575.             return 0;                                        // return no output
  576.     }
  577.                                                         // we must do this for short values
  578.     for (num = 0, count = 0; argsize; argsize--, count++){            // loop to assign num to numin
  579.         num |= numin & ((unsigned long)kBYTE_MASK) <<         // Mask off
  580.                                         (count * kBITS_PER_BYTE);
  581.                                                         // one byte at a time
  582.     }
  583.  
  584.     s = str;                                                // set current position
  585.     len = 0;                                                // init length to zero
  586.                                                         // OUTPUT STRING WILL BE REVERSED!
  587.     do {                                                    // loop to convert num into base
  588.         *s = (num % base) + kZero_CHAR;                        // get next digit
  589.         if (*s > kNine_CHAR) {                                // check for greater than nine
  590.                                                         // set output so 'A' or 'a' represents ten
  591.             *s = ((num % base) + ten_char) - kNumDecDigits;
  592.         }
  593.         s++;                                                // increment pointer for next char
  594.         len ++;                                            // increment output length
  595.     } while ((num /= base) > 0);                                // end when number is zero
  596.  
  597.                                                         // AT THIS POINT NUMBER IS REVERSED!
  598.  
  599.     while (len < zpaddlen) {                                    // check for leading zero padd
  600.         *s++ = kZero_CHAR;                                    // output zero
  601.         len ++;                                            // increment length
  602.     }
  603.     if (usesign) {                                            // check sign flag
  604.         if (negative) {                                        // check for negative number
  605.             *s++ = kMINUS_CHAR;                            // output '-'
  606.             len ++;                                        // increment length
  607.         }
  608.         else {                                            // number is positive        
  609.             if (showspace) {                                // check to ouput space for sign
  610.                 *s++ = kSpace_CHAR;                        // output ' '
  611.                 len ++;                                    // increment length
  612.             }
  613.             else {                                        // dont show space
  614.                 if (showplus) {                                // check to output '+'
  615.                     *s++ = kPLUS_CHAR;                        // output '+'
  616.                     len ++;                                // incrment length
  617.                 }
  618.             }
  619.         }
  620.     }
  621.     if (leftjustify == false) {                                    // check for right justify
  622.         while (len < spacepaddlen) {                            // add leading spaces
  623.             *s++ = kSpace_CHAR;                            // output next space
  624.             len ++;                                        // incremnt output length
  625.         }
  626.     }
  627.     else {                                                // left justify!
  628.                                                         // to left justify
  629.                                                         // the array needs to be shifted down
  630.                                                         // and spaces added to the begining
  631.                                                         // since number is reversed
  632.         count = spacepaddlen - len;                            // number of spaces to shift
  633.         if (count > 0) {                                        // must be at least one
  634.             numspaces = len;                                // number of bytes in array
  635.             for (p1 = (s + (count -1 )), p2 = s -1; numspaces--; p1--, p2--) {
  636.                 *p1 = *p2;                                // shift next byte
  637.             }
  638.             s += count;                                    // increment current position
  639.             for (; count-- ;) {                                // loop to add spaces
  640.                 *p1-- = kSpace_CHAR;                        // output a space
  641.                 len++;                                    // increment output length
  642.             }
  643.         }
  644.     }
  645.     *s = 0;                                                // null terminate C string
  646.                                                         // ouput string must now be
  647.                                                         // reversed for final output
  648.     for (p1 = str, p2 = (--s); p1 < p2; p1++, p2--) {                    // reverse loop
  649.         temp = *p1;                                        // swap
  650.         *p1 = *p2;                                        // *p1
  651.         *p2 = temp;                                        // with *p2
  652.     }
  653.     return len;                                            // return length of output
  654. }
  655.  
  656. Boolean TrapAvailable(unsigned short PatchTrap)
  657. {
  658.      return (NGetTrapAddress(PatchTrap, (PatchTrap & 0x0800) ? ToolTrap : OSTrap)) !=
  659.               (NGetTrapAddress(_Unimplemented, (_Unimplemented & 0x0800) ? ToolTrap : OSTrap));
  660. }
  661.